<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="FYutJ" id="FYutJ"><span data-lake-id="ua644242e" id="ua644242e">典型回答</span></h1>
  <p data-lake-id="u4cce39a7" id="u4cce39a7"><br></p>
  <p data-lake-id="u904e7aff" id="u904e7aff"><span data-lake-id="u5de90b85" id="u5de90b85">优化 Elasticsearch（ES）的查询性能涉及多个方面，从查询本身到集群配置和硬件资源。以下是一些关键的优化策略：</span></p>
  <h3 data-lake-id="d87c4c20" id="d87c4c20"><span data-lake-id="ua77793d1" id="ua77793d1">集群和硬件优化</span></h3>
  <ul list="u6835fd4e">
   <li fid="ubedb2feb" data-lake-id="ua2a25645" id="ua2a25645"><strong><span data-lake-id="u13cd2603" id="u13cd2603">负载均衡</span></strong><span data-lake-id="u19ca763a" id="u19ca763a">: 确保查询负载在集群中均衡分配。</span></li>
   <li fid="ubedb2feb" data-lake-id="u9ce756e0" id="u9ce756e0"><strong><span data-lake-id="u6ca93851" id="u6ca93851">硬件资源</span></strong><span data-lake-id="u09857f5d" id="u09857f5d">: 根据需要增加 CPU、内存或改善 I/O 性能（例如使用 SSD）。</span></li>
   <li fid="ubedb2feb" data-lake-id="uf67d2534" id="uf67d2534"><strong><span data-lake-id="u69ec0092" id="u69ec0092">配置 JVM</span></strong><span data-lake-id="u807b03f8" id="u807b03f8">: 优化 JVM 设置，如堆大小，以提高性能。</span></li>
  </ul>
  <p data-lake-id="u1b383ba3" id="u1b383ba3"><br></p>
  <h3 data-lake-id="dTdle" id="dTdle"><span data-lake-id="ude56d3bb" id="ude56d3bb">合理分片和副本</span></h3>
  <p data-lake-id="ufd6edb60" id="ufd6edb60"><br></p>
  <p data-lake-id="u31e45b47" id="u31e45b47"><span data-lake-id="uc696c539" id="uc696c539">虽然更多的分片可以提高写入吞吐量，因为可以并行写入多个分片。但是，查询大量分片可能会降低查询性能，因为每个分片都需要单独处理查询。而且分片数量过多可能会增加集群的管理开销和降低查询效率，尤其是在内存和文件句柄方面。所以，需要考虑数据量和硬件资源，合理设置分片数量。</span></p>
  <p data-lake-id="ue9e36796" id="ue9e36796"><span data-lake-id="uc84fb0b2" id="uc84fb0b2" class="lake-fontsize-12" style="color: rgb(15, 15, 15)">​</span><br></p>
  <p data-lake-id="u35bd3660" id="u35bd3660"><span data-lake-id="ufba76ac6" id="ufba76ac6">但是这个说起来比较玄学，毕竟没有一种“一刀切”的方法来确定最优的分片和副本数量，因为这取决于多种因素，包括数据的大小、查询的复杂性、硬件资源和预期的负载等。</span></p>
  <p data-lake-id="ueece21b4" id="ueece21b4"><br></p>
  <p data-lake-id="u6a9571ea" id="u6a9571ea"><em><span data-lake-id="u83fee059" id="u83fee059" class="lake-fontsize-12" style="color: rgb(52, 55, 65)">在ES每个节点上可以存储的分片数量与可用的堆内存大小成正比关系，但是 Elasticsearch 并未强制规定固定限值。这里有一个很好的经验法则：确保对于节点上已配置的每个 GB，将分片数量保持在 20 以下。如果某个节点拥有 30GB 的堆内存，那其最多可有 600 个分片，但是在此限值范围内，您设置的分片数量越少，效果就越好。一般而言，这可以帮助集群保持良好的运行状态。（来源参考：</span></em><a href="https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster" target="_blank" data-lake-id="u5bdade8e" id="u5bdade8e"><em><span data-lake-id="ub80358d1" id="ub80358d1" class="lake-fontsize-12" style="color: rgb(52, 55, 65)">https://www.elastic.co/cn/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster</span></em></a><em><span data-lake-id="ud6632635" id="ud6632635" class="lake-fontsize-12" style="color: rgb(52, 55, 65)"> ）</span></em></p>
  <p data-lake-id="u81efc9a8" id="u81efc9a8"><br></p>
  <h3 data-lake-id="HJcxV" id="HJcxV"><span data-lake-id="ue16515f2" id="ue16515f2">精确的映射和索引设置</span></h3>
  <p data-lake-id="ub97d27bb" id="ub97d27bb"><br></p>
  <p data-lake-id="ue9b8ea17" id="ue9b8ea17"><span data-lake-id="u788eda05" id="u788eda05" class="lake-fontsize-12" style="color: rgb(15, 15, 15)">映射（Mapping）是定义如何存储和索引文档中字段的规则。我们可以在以下几个方面做一些优化：</span></p>
  <p data-lake-id="ue55fa2ba" id="ue55fa2ba"><span data-lake-id="ueb32dbc6" id="ueb32dbc6" class="lake-fontsize-12" style="color: rgb(15, 15, 15)">​</span><br></p>
  <p data-lake-id="u7bc0e19f" id="u7bc0e19f"><span data-lake-id="u15974a42" id="u15974a42">确切定义字段类型：为每个字段指定正确的数据类型（如 text, keyword, date, integer 等），这是因为不同的数据类型有不同的存储和索引方式。需要注意的是：</span><code data-lake-id="u1ad7bc7a" id="u1ad7bc7a"><span data-lake-id="u9b5b254d" id="u9b5b254d">text </span></code><span data-lake-id="u9c76b531" id="u9c76b531">类型用于全文搜索，它会被分析（analyzed），即分解为单个词项。</span><code data-lake-id="ub85dcfe7" id="ub85dcfe7"><span data-lake-id="ue6d28b0d" id="ue6d28b0d">keyword</span></code><span data-lake-id="u18dcbb14" id="u18dcbb14"> 类型用于精确值匹配，过滤，排序和聚合。它不会被分析。</span></p>
  <p data-lake-id="u67c80891" id="u67c80891"><span data-lake-id="u90e6c7c9" id="u90e6c7c9">​</span><br></p>
  <p data-lake-id="ubc16083c" id="ubc16083c"><span data-lake-id="u65c17055" id="u65c17055">根据需要选择合适的分析器（Analyzer），对于 </span><code data-lake-id="ue8455c3c" id="ue8455c3c"><span data-lake-id="ud60baa45" id="ud60baa45">text</span></code><span data-lake-id="u2cfd1551" id="u2cfd1551"> 类型的字段，可以指定分析器来定义文本如何被分割和索引。对于不需要全文搜索的字段，使用 </span><code data-lake-id="uecb08887" id="uecb08887"><span data-lake-id="uf2c2a0da" id="uf2c2a0da">keyword</span></code><span data-lake-id="uc2d6370a" id="uc2d6370a"> 类型以避免分析开销。</span></p>
  <p data-lake-id="u1f299332" id="u1f299332"><br></p>
  <h3 data-lake-id="ec81a0a9" id="ec81a0a9"><span data-lake-id="u14917de7" id="u14917de7">查询优化</span></h3>
  <p data-lake-id="u3996ef1f" id="u3996ef1f"><br></p>
  <p data-lake-id="u3d871e24" id="u3d871e24"><span data-lake-id="ue2903dd0" id="ue2903dd0">很多人用ES很慢，是因为自己的查询本身就用的不对，我们可以尝试着优化一下你的查询。如：</span></p>
  <p data-lake-id="u38670953" id="u38670953"><br></p>
  <ul list="u5532f5f2">
   <li fid="u95a02266" data-lake-id="uaead2593" id="uaead2593"><strong><span data-lake-id="u77d4e25d" id="u77d4e25d">避免高开销查询</span></strong><span data-lake-id="u9f3bd744" id="u9f3bd744">: 如 </span><code data-lake-id="u0de984ac" id="u0de984ac"><span data-lake-id="u8e313394" id="u8e313394">wildcard</span></code><span data-lake-id="u9066fb7b" id="u9066fb7b">、</span><code data-lake-id="u3ff9d737" id="u3ff9d737"><span data-lake-id="uf618e1f4" id="uf618e1f4">regexp</span></code><span data-lake-id="u57f708d3" id="u57f708d3"> 等类型的查询往往开销较大，尽量避免使用或优化其使用方式。</span></li>
   <li fid="u95a02266" data-lake-id="u185cb592" id="u185cb592"><strong><span data-lake-id="ud176b025" id="ud176b025">使用过滤器</span></strong><span data-lake-id="ucc9ffb13" id="ucc9ffb13">: 对于不需要评分的查询条件，使用 </span><code data-lake-id="u50f25a2c" id="u50f25a2c"><span data-lake-id="ue6b32f70" id="ue6b32f70">filter</span></code><span data-lake-id="udd38eeaf" id="udd38eeaf"> 而不是 </span><code data-lake-id="ua5043bc7" id="ua5043bc7"><span data-lake-id="ua7e36f95" id="ua7e36f95">query</span></code><span data-lake-id="u1578f1c1" id="u1578f1c1">，因为 </span><code data-lake-id="ub2566562" id="ub2566562"><span data-lake-id="ub23dffc7" id="ub23dffc7">filter</span></code><span data-lake-id="ud8a8f915" id="ud8a8f915"> 可以被缓存以加快后续相同查询的速度。</span></li>
   <li fid="u95a02266" data-lake-id="u6a8d823b" id="u6a8d823b"><strong><span data-lake-id="u236b1bb4" id="u236b1bb4">查询尽可能少的字段</span></strong><span data-lake-id="ua46bf077" id="ua46bf077">: 只返回查询中需要的字段，减少数据传输和处理时间。</span></li>
   <li fid="u95a02266" data-lake-id="u44df9a0a" id="u44df9a0a"><strong><span data-lake-id="ufaff861d" id="ufaff861d">避免深度分页</span></strong><span data-lake-id="u1dab535b" id="u1dab535b">: 避免深度分页，对于需要处理大量数据的情况，考虑使用 </span><code data-lake-id="u6f3e47b5" id="u6f3e47b5"><span data-lake-id="ue4bbe405" id="ue4bbe405">search_after</span></code><span data-lake-id="uc5ba800d" id="uc5ba800d">。</span></li>
   <li fid="u95a02266" data-lake-id="ua123a3d0" id="ua123a3d0"><strong><span data-lake-id="u939b3d25" id="u939b3d25">避免使用脚本</span></strong><span data-lake-id="u2b467815" id="u2b467815">：尽量避免使用脚本（Script）查询，因为它们通常比简单查询要慢。（脚本执行通常比静态查询更消耗资源。每次执行脚本时，都需要进行编译（除非缓存）和运行，这会增加CPU和内存的使用。脚本执行不能利用索引，因此可能需要全面扫描文档。）</span></li>
   <li fid="u95a02266" data-lake-id="u77b8cb29" id="u77b8cb29"><strong><span data-lake-id="ucf679de7" id="ucf679de7">使用 match 而非 term 查询文本字段</span></strong><span data-lake-id="ube28a504" id="ube28a504">：match 查询会分析查询字符串，而 term 查询不会，适用于精确值匹配。</span></li>
   <li fid="u95a02266" data-lake-id="u8c78e0a0" id="u8c78e0a0"><strong><span data-lake-id="u61668cb7" id="u61668cb7">避免使用通配符、正则表达式</span></strong><span data-lake-id="u58e4e0fd" id="u58e4e0fd">：这类查询往往非常消耗资源，特别是以通配符开头的（如 *text）。</span></li>
   <li fid="u95a02266" data-lake-id="u273d6016" id="u273d6016"><strong><span data-lake-id="u12e5667c" id="u12e5667c">合理使用聚合</span></strong><span data-lake-id="ud18145cd" id="ud18145cd">：聚合可以用于高效地进行数据分析，但复杂的聚合也可能非常消耗资源。优化聚合查询，如通过限制桶的数量，避免过度复杂的嵌套聚合。</span></li>
  </ul>
  <p data-lake-id="ua2ce2c1e" id="ua2ce2c1e"><br></p>
  <h3 data-lake-id="585d8f5a" id="585d8f5a"><span data-lake-id="u7a424056" id="u7a424056">使用缓存</span></h3>
  <p data-lake-id="u842b8f53" id="u842b8f53"><br></p>
  <ul list="u5580cb16">
   <li fid="u49bfbd79" data-lake-id="u32229002" id="u32229002"><strong><span data-lake-id="u1fa1c29b" id="u1fa1c29b">请求缓存</span></strong><span data-lake-id="u84826646" id="u84826646">: 对于不经常变化的数据，利用 ES 的请求缓存机制。</span></li>
   <li fid="u49bfbd79" data-lake-id="u1acd5a10" id="u1acd5a10"><strong><span data-lake-id="uabe35b3f" id="uabe35b3f">清理缓存</span></strong><span data-lake-id="u1e5eebef" id="u1e5eebef">: 定期清理不再需要的缓存，释放资源。</span></li>
  </ul>
  <p data-lake-id="u36f3cfc9" id="u36f3cfc9"><br></p>
  <h3 data-lake-id="cf5f16a8" id="cf5f16a8"><span data-lake-id="u52aca9c2" id="u52aca9c2">监控和分析</span></h3>
  <p data-lake-id="ua8e93462" id="ua8e93462"><br></p>
  <ul list="uc909db1d">
   <li fid="u462c5793" data-lake-id="u627ef383" id="u627ef383"><strong><span data-lake-id="ude86e2ec" id="ude86e2ec">监控</span></strong><span data-lake-id="u2572be7e" id="u2572be7e">: 使用 Kibana、Elasticsearch-head、Elastic HQ 等工具监控集群状态和性能。</span></li>
   <li fid="u462c5793" data-lake-id="u80d8dc97" id="u80d8dc97"><strong><span data-lake-id="u20b0f890" id="u20b0f890">慢查询日志</span></strong><span data-lake-id="u0058bc5c" id="u0058bc5c">: 启用慢查询日志来识别和优化慢查询。</span></li>
  </ul>
  <h3 data-lake-id="631cb1ca" id="631cb1ca"><br></h3>
 </body>
</html>